<template>
    <div :style="{width}">
        <div class="map-search">
            <el-input @keyup.enter="getLatLngBounds" class="search" placeholder="输入搜索地址" style="width:200px" type="text" v-model="address" />
            <el-button @click="getLatLngBounds" class="ml-10" type="primary">搜索</el-button>
        </div>

        <div :style="{width, height}" id="map"></div>

        <!-- 周边位置 -->
        <div :style="{height: boundsHeight}" class="bounds" ref="bounds">
            <div :key="index" @click="selectCity(index)" class="list" v-for="(item, index) in BoundsPois">
                <div>
                    <p class="name">{{item.name}}</p>
                    <span class="address">{{item.address}}</span>
                </div>
                <span :class="{on: selectPosition == index}" class="yes"></span>
            </div>
        </div>
    </div>
</template>
  
  <script>
export default {
    props: {
        //地图key
        mapKey: {
            type: String,
            default: 'F37BZ-ZXELU-KOWVT-BWN72-3ELF6-GEFIH',
        },
        //设置地图宽度
        width: {
            type: String,
            default: '600px',
        },
        //设置地图高度
        height: {
            type: String,
            default: '400px',
        },
        //周边位置高度
        boundsHeight: {
            type: String,
            default: '200px',
        },
        longitude: {
            default: 39.916527,
        },
        latitude: {
            default: 116.397128,
        },
    },
    data() {
        return {
            latLng: [this.longitude, this.latitude], //默认位置，之后会自动定位到当前位置。

            address: '', //搜索关键字
            marker: null, //标记点
            map: null, //地图实例

            //获取周边区域定时器
            setTime: null,
            selectPosition: -1, //选择的位置
            BoundsPois: [], //周边列表
        }
    },

    mounted() {
        this.loadScript()
    },

    methods: {
        //异步加载地图js
        loadScript() {
            var script = document.createElement('script')
            script.type = 'text/javascript'
            script.charset = 'utf-8'
            //地图js加载完成的回调，初始化地图
            window.initMap = () => {
                this.init()
            }
            script.src = 'https://map.qq.com/api/js?v=2.exp&key=' + this.mapKey + '&callback=initMap'
            document.body.appendChild(script)
        },

        //初始化地图
        init() {
            this.map = new qq.maps.Map(document.getElementById('map'), {
                center: new qq.maps.LatLng(this.latLng[0], this.latLng[1]), //设置地图中心的
                keyboardShortcuts: false, //禁止键盘操控
                disableDefaultUI: true, //禁止所有控件
                zoom: 18,
            })
            //获取当前位置
            this.$nextTick(() => {
                this.getLocation(this.latLng)
            })
            //绑定地图点击事件
            qq.maps.event.addListener(this.map, 'click', (e) => {
                // this.getLatLng(e);
            })
            //绑定地图中心点改变事件
            qq.maps.event.addListener(this.map, 'center_changed', (e) => {
                if (this.selectPosition != -1) return
                this.centerChanged(e)
            })
            //绑定地图开始拖动事件
            qq.maps.event.addListener(this.map, 'dragstart', (e) => {
                //重置选择、搜索框
                this.address = ''
                this.selectPosition = -1
            })
            //绑定地图缩放级别更改事件
            qq.maps.event.addListener(this.map, 'zoom_changed', (e) => {
                //重置选择、搜索框
                this.address = ''
                this.selectPosition = -1
            })
        },

        //点击地图，获取定位度
        getLatLng(e) {
            this.$emit('getLatLng', [e.latLng.lat, e.latLng.lng])
        },

        //地图中心点改变事件
        centerChanged(e, type) {
            let center = this.map.getCenter()
            if (this.marker) {
                //设置标注点为中心点
                this.marker.setPosition(center)
                //设置标注点下落动画
                this.marker.setAnimation(qq.maps.MarkerAnimation.DOWN)
                clearTimeout(this.setTime)
                this.setTime = setTimeout(() => {
                    this.getAddress()
                }, 500)
            }
        },

        //查询位置
        searchCity() {
            let geocoder = new qq.maps.Geocoder({
                complete: (result) => {
                    this.map.setCenter(result.detail.location)
                    //设置标注点位置
                    this.marker.setPosition(result.detail.location)
                    //设置标注点下落动画
                    this.marker.setAnimation(qq.maps.MarkerAnimation.DOWN)
                },
            })
            geocoder.getLocation(this.address)
        },

        //搜索位置，查询周边位置信息
        getLatLngBounds(init) {
            this.selectPosition = -1
            let latlngBounds = new qq.maps.LatLngBounds()
            //调用Poi检索类
            let searchService = new qq.maps.SearchService({
                complete: (results) => {
                    this.scrollTop()
                    this.BoundsPois = results.detail.pois
                    this.map.setCenter(this.BoundsPois[0].latLng)
                    //设置标注点为中心点
                    this.marker.setPosition(this.BoundsPois[0].latLng)
                },
            })
            //周边位置个数10个
            searchService.setPageCapacity(10)
            searchService.searchInBounds(this.address, latlngBounds) //根据范围和关键字进行指定区域检索。
        },

        //根据经纬度进行位置解析
        getAddress(latLng) {
            let geocoder = new qq.maps.Geocoder({
                complete: (result) => {
                    this.scrollTop()
                    this.$emit('getLatLng', [result.detail.location.lat, result.detail.location.lng])
                    //添加当前的经纬度信息
                    let nowPostin = { name: '当前标注位置', address: result.detail.address, latLng: { lat: result.detail.location.lat, lng: result.detail.location.lng } }
                    this.BoundsPois = [nowPostin, ...result.detail.nearPois]
                },
            })
            geocoder.getAddress(latLng || this.map.getCenter())
        },

        //选择周边滚动条返回到顶部
        scrollTop() {
            this.$refs.bounds.scrollTop = 0
        },

        //在列表中选择位置
        selectCity(index) {
            this.selectPosition = index
            let lat = this.BoundsPois[index].latLng.lat,
                lng = this.BoundsPois[index].latLng.lng,
                latLng = new qq.maps.LatLng(lat, lng)
            //将地图中心移至当前坐标
            this.map.panTo(latLng)
            //设置标注点位置
            this.marker.setPosition(latLng)
            //设置标注点下落动画
            this.marker.setAnimation(qq.maps.MarkerAnimation.DOWN)
            this.$emit('getLatLng', [lat, lng])
        },

        //获取当前位置
        getLocation(latLng = null) {
            let cs = new qq.maps.CityService({
                map: this.map,
                complete: (results) => {
                    if (latLng != null && latLng[0] != '') {
                        let re_value = results.detail.latLng
                        re_value.lat = latLng[0]
                        re_value.lng = latLng[1]
                        this.map.setCenter(re_value)
                        //设置标注点为当前中心位置
                        this.setMarker(re_value)
                        //获取当前位置的周边范围
                        this.getAddress()
                    } else {
                        this.latLng = [results.detail.latLng.lat, results.detail.latLng.lng]
                        //设置地图中心位置为当前定位。
                        this.map.setCenter(results.detail.latLng)
                        //设置标注点为当前中心位置
                        this.setMarker(results.detail.latLng)
                        //获取当前位置的周边范围
                        this.getAddress()
                    }
                },
            })
            //调用searchLocalCity()方法获取位置
            cs.searchLocalCity()
        },

        //设置底部标记点
        setMarker(center) {
            let icon = new qq.maps.MarkerImage(
                '',
                new qq.maps.Size(52, 73),
                new qq.maps.Point(0, 0),
                new qq.maps.Point(12, 34),
                new qq.maps.Size(25, 35)
            )
            let iconb = new qq.maps.MarkerImage('', new qq.maps.Size(16, 16), new qq.maps.Point(0, 0), new qq.maps.Point(5, 5), new qq.maps.Size(10, 10))

            this.marker = new qq.maps.Marker({
                map: this.map,
                position: center,
            })
            this.marker.setIcon(icon)
            this.marker.setShadow(iconb)
        },
    },
}
</script>
  
<style lang="scss" scoped>
.map-search {
    display: flex;
    // justify-content: center;
    align-items: center;
    padding-bottom: 20px;
}
.bounds {
    height: 200px;
    border-top: 1px solid #d3d3d3;
    background-color: #fff;
    overflow-y: auto;
    .list {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 10px;
        border-bottom: 1px solid #d3d3d3;
        cursor: pointer;
        .name {
            margin: 0;
            font-size: 14px;
        }
        .address {
            font-size: 12px;
            color: gray;
        }
        .yes {
            position: relative;
            display: inline-block;
            &.on {
                &::after {
                    background-color: #409eff;
                }
                &::before {
                    background-color: #409eff;
                }
            }
            &::after {
                content: '';
                position: absolute;
                right: 10px;
                width: 20px;
                height: 2px;
                border-radius: 20px;
                transform: rotate(-45deg);
            }
            &::before {
                content: '';
                position: absolute;
                right: 25px;
                top: 3px;
                width: 10px;
                height: 2px;
                border-radius: 20px;
                transform: rotate(45deg);
            }
        }
    }
}
</style>